﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AG.Editor.Core.Metadata;
using System.Xml.Linq;
using AG.Editor.Core.Data;

namespace AG.Editor.Core
{
    public class AGXML1_0
    {
        public static AGTProjectSummary ConvertTProjectSummaryFromXml(XElement xEl)
        {
            string ver = xEl.Attribute("ver").Value;
            string name = xEl.Attribute("n").Value;
            string caption = xEl.Attribute("c").Value;
            AGTProjectSummary summary = new AGTProjectSummary();
            summary.Name = name;
            summary.Caption = caption;
            summary.Version = ver;
            return summary;
        }

        public static AGTProject ConvertTProjectFromXml(XElement xEl)
        {
            string ver = xEl.Attribute("ver").Value;
            string name = xEl.Attribute("n").Value;
            string caption = xEl.Attribute("c").Value;
            AGTProject tProject = new AGTProject();
            tProject.Name = name;
            tProject.Caption = caption;
            tProject.Version = ver;

            List<XElement> xAcList = xEl.Element("ac").Elements("aci").ToList();
            foreach (XElement xAci in xAcList)
            {
                tProject.AudioCateogries.Add(ConvertAudioCategoryFromXml(xAci));
            }

            List<XElement> xMciLst = xEl.Element("mc").Elements("mci").ToList();
            foreach (XElement xMci in xMciLst)
            {
                tProject.ModelCategories.Add(ConvertModelCategoryFromXml(xMci));
            }

            return tProject;
        }

        #region audio category
        private static AGAudioCategory ConvertAudioCategoryFromXml(XElement xAci)
        {
            AGAudioCategory category = new AGAudioCategory();
            category.Id = xAci.XGetAttrIntValue("i", AGECONST.INT_NULL);
            category.Caption = xAci.XGetAttrStringValue("c", AGECONST.STRING_NULL);
            return category;
        }
        #endregion

        #region model category
        private static AGModelCategory ConvertModelCategoryFromXml(XElement xMci)
        {
            string id = xMci.Attribute("i").Value;
            string caption = xMci.Attribute("c").Value;
            int dir = Convert.ToInt32(xMci.Attribute("dir").Value);

            List<XElement> xActs = xMci.Elements("act").ToList();

            AGModelCategory category = new AGModelCategory();
            category.Id = Convert.ToInt32(id);
            category.Caption = caption;
            if (dir == 1)
            {
                category.DirectionMode = AGDirectionMode.One;
            }
            else if (dir == 2)
            {
                category.DirectionMode = AGDirectionMode.Two;
            }
            else if (dir == 4)
            {
                category.DirectionMode = AGDirectionMode.Four;
            }
            else if (dir == 8)
            {
                category.DirectionMode = AGDirectionMode.Eight;
            }
            else if (dir == 16)
            {
                category.DirectionMode = AGDirectionMode.Sixteen;
            }

            foreach (var xAct in xActs)
            {
                int actId = Convert.ToInt32(xAct.Attribute("i").Value);
                string actCaption = xAct.Attribute("c").Value;

                AGAction action = new AGAction(actId);
                action.Caption = actCaption;

                for (int dirIndex = 0; dirIndex < dir; dirIndex++)
			    {
                    AGDirection direction = new AGDirection(dirIndex);
                    direction.Caption = AGDirection.GetCaption(category.DirectionMode, direction.Id);
                    action.Directions.Add(direction);
                }

                category.Actions.Add(action);
            }

            return category;
        }
        #endregion


        public static void ConvertTemplateToXml(XElement xTemplate, AGTProject template)
        {
            xTemplate.Add(new XAttribute("n", template.Name));
            xTemplate.Add(new XAttribute("c", template.Caption));
            xTemplate.Add(new XAttribute("ver", template.Version));

            XElement xAudioList = new XElement("ac");
            xTemplate.Add(xAudioList);
            for (int index = 0; index < template.AudioCateogries.Count; index++)
            {
                AGAudioCategory ac = template.AudioCateogries[index];
                XElement xAc = new XElement("aci");
                xAudioList.Add(xAc);
                ConvertAudioCategoryToXml(xAc, ac);
            }

            XElement xModelList = new XElement("mc");
            xTemplate.Add(xModelList);
            for (int index = 0; index < template.ModelCategories.Count; index++)
            {
                AGModelCategory mc = template.ModelCategories[index];
                XElement xMc = new XElement("mci");
                xModelList.Add(xMc);
                ConvertModelCategoryToXml(xMc, mc);
            }
        }

        private static void ConvertAudioCategoryToXml(XElement xAc, AGAudioCategory category)
        {
            xAc.Add(new XAttribute("i", category.Id));
            xAc.Add(new XAttribute("c", category.Caption));
        }

        private static void ConvertModelCategoryToXml(XElement xMci, AGModelCategory category)
        {
            int dir = 1;
            if (category.DirectionMode == AGDirectionMode.One)
            {
                dir = 1;
            }
            else if (category.DirectionMode == AGDirectionMode.Two)
            {
                dir = 2;
            }
            else if (category.DirectionMode == AGDirectionMode.Four)
            {
                dir = 4;
            }
            else if (category.DirectionMode == AGDirectionMode.Eight)
            {
                dir = 8;
            }
            else if (category.DirectionMode == AGDirectionMode.Sixteen)
            {
                dir = 16;
            }

            xMci.Add(new XAttribute("i", category.Id));
            xMci.Add(new XAttribute("c", category.Caption));
            xMci.Add(new XAttribute("dir", dir));

            for (int index = 0; index < category.Actions.Count; index++)
            {
                AGAction action = category.Actions[index];

                XElement xAct = new XElement("act");
                xMci.Add(xAct);

                xAct.Add(new XAttribute("i", action.Id));
                xAct.Add(new XAttribute("c", action.Caption));
            }
        }

        #region terrain
        public static AGTerrain ConvertTerrainFromXml(XElement xTerrain)
        {
            AGTerrain terrain = new AGTerrain();
            terrain.Id = (byte)xTerrain.XGetAttrIntValue("id", AGECONST.INT_NULL);
            terrain.ForegroundId = (byte)xTerrain.XGetAttrIntValue("foreground", AGECONST.INT_NULL);
            terrain.BackgroundId = (byte)xTerrain.XGetAttrIntValue("background", AGECONST.INT_NULL);
            terrain.Name = xTerrain.XGetAttrStringValue("name", AGECONST.STRING_NULL);
            terrain.ModelUniqueId = xTerrain.XGetAttrGuid("model-unique-id");
            List<XElement> xTileList = xTerrain.XGetElements("tile").ToList();
            for (int index = 0; index < xTileList.Count; index++)
            {
                XElement xTile = xTileList[index];
                int tileId = xTile.XGetAttrInt("id");
                int tileCount = xTile.XGetAttrInt("count");
                AGTerrainTile tile = new AGTerrainTile();
                tile.Id = (byte)tileId;
                tile.Count = (byte)tileCount;
                tile.Caption = xTile.XGetAttrString("caption");
                terrain.Tiles.Add(tile);
            }

            return terrain;
        }

        public static void ConvertTerrainToXml(XElement xTerrain, AGTerrain terrain)
        {
            xTerrain.Add(new XAttribute("id", terrain.Id));
            xTerrain.Add(new XAttribute("foreground", terrain.ForegroundId));
            xTerrain.Add(new XAttribute("background", terrain.BackgroundId));
            xTerrain.Add(new XAttribute("name", terrain.Name));
            xTerrain.Add(new XAttribute("model-unique-id", terrain.ModelUniqueId));

            for (int index = 0; index < terrain.Tiles.Count; index++)
            {
                AGTerrainTile tile = terrain.Tiles[index];
                XElement xTile = new XElement("tile");
                xTerrain.Add(xTile);

                xTile.Add(new XAttribute("id", tile.Id));
                xTile.Add(new XAttribute("count", tile.Count));
                xTile.Add(new XAttribute("caption", tile.Caption));
            }
        }
        #endregion
    }
}
